package util.bean;

import com.sun.istack.internal.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.BaseUtil;

import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Objects;

/**
 * @author yangfan
 * @description 操作bean util
 * @date 2018/5/15 14:49
 * @since 1.8
 **/

public class BeanUtil extends BaseUtil {

	private final static Logger LOGGER = LoggerFactory.getLogger(BeanUtil.class);

	private BeanUtil() {
		LOGGER.debug("BeanUtil");
		throw new AssertionError(getClass().getName() + " has no default instances.");
	}

	/**
	 * convert object to map
	 *
	 * @param obj convert object
	 * @return the hashMap of object
	 */
	public static HashMap convertBeanToMap(Object obj) {
		Class beanClass = obj.getClass();
		HashMap beanMap = new HashMap();
		try {
			Field[] fields = beanClass.getDeclaredFields();
			for (Field field : fields) {
				//设置可访问
				field.setAccessible(true);
				Alias annotation = field.getAnnotation(Alias.class);
				if (Objects.nonNull(annotation)) {
					beanMap.put(annotation.alias(), field.get(obj));
				} else {
					beanMap.put(field.getName(), field.get(obj));
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return beanMap;
	}

	/**
	 * 序列化
	 *
	 * @param oldObject 准备克隆的旧对象
	 * @return <T extends Serializable> 实现序列化接口的对象
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public static <T extends Serializable> T beanDeepClone(@NotNull T oldObject) {

		//新对象
		T newObject = null;

		try {
			//对对象进行序列化
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);

			//对象读取
			outputStream.writeObject(oldObject);
			outputStream.close();

			//内存读取对象，写入原始对象，生成对象
			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
			ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
			newObject = (T) inputStream.readObject();
			inputStream.close();

		} catch (ClassNotFoundException | IOException e) {
			e.printStackTrace();
		}

		return newObject;
	}

	/**
	 * judge properties of object are all not null
	 *
	 * @param obj judge object
	 * @return true properties are all not null
	 * @throws Exception
	 */
	public boolean isAllPropertiesNotNull(Object obj) throws IllegalAccessException {
		Class stuCla = obj.getClass();// 得到类对象
		Field[] fs = stuCla.getDeclaredFields();//得到属性集合
		boolean flag = false;
		for (Field f : fs) {//遍历属性
			f.setAccessible(true); // 设置属性是可以访问的
			Object val = f.get(obj);// 得到此属性的值
			if (!"serialVersionUID".equals(f.getName())) {
				if (val != null) {//只要有1个属性不为空,那么就不是所有的属性值都为空
					flag = true;
					break;
				}
			}
		}
		return flag;
	}
}
